import type { FileInfo as FileItem } from '#/api/openapi';

import { client } from '#/api/core/client';

/**
 * 文件预览服务
 * 提供文件预览相关的API调用封装
 */
export const FilePreviewService = {
  /**
   * 获取文件预览URL
   * @param file 文件信息
   * @param shareCode 分享码
   * @returns 预览URL
   */
  getPreviewUrl(file: FileItem, shareCode: string): string {
    if (!file.md5 || !shareCode) {
      return '';
    }

    const basePath =
      import.meta.env.VITE_API_BASE_URL || 'http://localhost:8081';
    return `${basePath}/api/preview/${shareCode}/${file.md5}`;
  },

  /**
   * 获取文件缩略图URL
   * @param file 文件信息
   * @param shareCode 分享码
   * @param width 宽度
   * @param height 高度
   * @returns 缩略图URL
   */
  getThumbnailUrl(
    file: FileItem,
    shareCode: string,
    width?: number,
    height?: number,
  ): string {
    if (!file.md5 || !shareCode) {
      return '';
    }

    const basePath =
      import.meta.env.VITE_API_BASE_URL || 'http://localhost:8081';
    let url = `${basePath}/api/preview/thumbnail/${shareCode}/${file.md5}`;

    const params = new URLSearchParams();
    if (width) params.append('width', width.toString());
    if (height) params.append('height', height.toString());

    if (params.toString()) {
      url += `?${params.toString()}`;
    }

    return url;
  },

  /**
   * 获取流媒体预览URL
   * @param file 文件信息
   * @param shareCode 分享码
   * @returns 流媒体URL
   */
  getStreamUrl(file: FileItem, shareCode: string): string {
    if (!file.md5 || !shareCode || !file.fileName) {
      return '';
    }

    const basePath =
      import.meta.env.VITE_API_BASE_URL || 'http://localhost:8081';
    return `${basePath}/api/preview/stream/${shareCode}/${file.md5}/${encodeURIComponent(file.fileName)}`;
  },

  /**
   * 检查文件是否支持预览
   * @param file 文件信息
   * @returns 是否支持预览
   */
  isPreviewSupported(file: FileItem): boolean {
    if (!file.fileName) return false;

    const ext = file.fileName.split('.').pop()?.toLowerCase();
    if (!ext) return false;

    // 支持预览的文件类型
    const supportedTypes = [
      // 图片
      'jpg',
      'jpeg',
      'png',
      'gif',
      'webp',
      'svg',
      'bmp',
      // 文档
      'pdf',
      'txt',
      'md',
      'json',
      'xml',
      'yaml',
      'yml',
      // 代码
      'js',
      'ts',
      'vue',
      'html',
      'css',
      'jsx',
      'tsx',
      // 视频
      'mp4',
      'webm',
      'ogg',
      'avi',
      'mov',
      // 音频
      'mp3',
      'wav',
      'ogg',
      'aac',
      'flac',
    ];

    return supportedTypes.includes(ext);
  },

  /**
   * 获取文件类型分类
   * @param file 文件信息
   * @returns 文件类型分类
   */
  getFileType(
    file: FileItem,
  ): 'audio' | 'document' | 'image' | 'other' | 'text' | 'video' {
    if (!file.fileName) return 'other';

    const ext = file.fileName.split('.').pop()?.toLowerCase();
    if (!ext) return 'other';

    const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp'];
    const videoExts = ['mp4', 'webm', 'ogg', 'avi', 'mov', 'wmv', 'flv'];
    const audioExts = ['mp3', 'wav', 'ogg', 'aac', 'flac', 'wma'];
    const documentExts = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'];
    const textExts = [
      'txt',
      'md',
      'json',
      'js',
      'ts',
      'vue',
      'html',
      'css',
      'xml',
      'yaml',
      'yml',
    ];

    if (imageExts.includes(ext)) return 'image';
    if (videoExts.includes(ext)) return 'video';
    if (audioExts.includes(ext)) return 'audio';
    if (documentExts.includes(ext)) return 'document';
    if (textExts.includes(ext)) return 'text';

    return 'other';
  },

  /**
   * 获取文件预览信息
   * @param shareCode 分享码
   * @param md5 文件MD5
   * @returns 预览信息
   */
  async getFilePreview(shareCode: string, md5: string) {
    try {
      const response = await client.filePreview.getFilePreview(shareCode, md5);
      return response.data;
    } catch (error) {
      console.error('获取文件预览信息失败:', error);
      throw error;
    }
  },

  /**
   * 获取缩略图
   * @param shareCode 分享码
   * @param md5 文件MD5
   * @param width 宽度
   * @param height 高度
   * @returns 缩略图数据
   */
  async getThumbnail(
    shareCode: string,
    md5: string,
    width?: number,
    height?: number,
  ) {
    try {
      const response = await client.filePreview.getThumbnail(
        shareCode,
        md5,
        width,
        height,
      );
      return response.data;
    } catch (error) {
      console.error('获取缩略图失败:', error);
      throw error;
    }
  },

  /**
   * 流式获取文件
   * @param shareCode 分享码
   * @param md5 文件MD5
   * @param fileName 文件名
   * @param range 范围请求头
   * @returns 文件流
   */
  async streamFile(
    shareCode: string,
    md5: string,
    fileName: string,
    range?: string,
  ) {
    try {
      const response = await client.filePreview.streamFile(
        shareCode,
        md5,
        fileName,
        range,
      );
      return response.data;
    } catch (error) {
      console.error('流式获取文件失败:', error);
      throw error;
    }
  },

  /**
   * 检查预览URL是否可访问
   * @param url 预览URL
   * @returns 是否可访问
   */
  async checkUrlAccessible(url: string): Promise<boolean> {
    try {
      const response = await fetch(url, { method: 'HEAD' });
      return response.ok;
    } catch {
      return false;
    }
  },

  /**
   * 获取文件内容（用于文本文件）
   * @param file 文件信息
   * @param shareCode 分享码
   * @returns 文件内容
   */
  async getFileContent(file: FileItem, shareCode: string): Promise<string> {
    const url = this.getPreviewUrl(file, shareCode);
    if (!url) {
      throw new Error('无法生成预览URL');
    }

    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      // 检查内容类型
      const contentType = response.headers.get('content-type') || '';
      if (
        !contentType.includes('text/') &&
        !contentType.includes('application/json')
      ) {
        throw new Error('文件不是文本格式');
      }

      const content = await response.text();
      return content;
    } catch (error) {
      console.error('获取文件内容失败:', error);
      throw error;
    }
  },
};

/**
 * 文件预览工具函数
 */
export const filePreviewUtils = {
  /**
   * 获取预览URL的简便方法
   */
  getUrl: FilePreviewService.getPreviewUrl,

  /**
   * 获取缩略图URL的简便方法
   */
  getThumbnailUrl: FilePreviewService.getThumbnailUrl,

  /**
   * 获取流媒体URL的简便方法
   */
  getStreamUrl: FilePreviewService.getStreamUrl,

  /**
   * 检查是否支持预览的简便方法
   */
  isSupported: FilePreviewService.isPreviewSupported,

  /**
   * 获取文件类型的简便方法
   */
  getType: FilePreviewService.getFileType,
};
